#
# Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
#
#   GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
#   Author :  Shawn.Tan
#   Date : 2025.10.28
#
#   History : Initial Version 2025.10.28
#
#
from base.Env import Env, GlobalInitSequence
from gpgpu.ThreadSplitterSequence import ThreadSplitterSequence
import gpgpu.PcConfig as PcConfig
from Constraint import ConstraintSet
import Log

#  GlobalInitSeqGPGPU class
# Return arch specific information to base GlobalInitSequence class


class GlobalInitSeqGPGPU(GlobalInitSequence):
    def __init__(self, gen_thread, name):
        super().__init__(gen_thread, name)

    def setupResetRegion(self):
        self.setGlobalState("ResetPC", PcConfig.get_reset_pc())
        self.virtualMemoryRequest(
            "PhysicalRegion",
            {
                "RegionType": "ResetRegion",
                "Size": PcConfig.get_reset_region_size(),
                "Type": "I",
                "Bank": 0,
            },
        )

        (skip_boot, skip_boot_valid) = self.genThread.getOption("SkipBootCode")
        if skip_boot_valid and skip_boot == 1:
            self.setGlobalState("ResetPC", PcConfig.get_base_initial_pc())

    def allocateHandlerSetMemory(self):
        handler_memory_constr = self._getHandlerMemoryConstraint()
        handler_memory_size = self.getHandlerMemorySize()
        self.virtualMemoryRequest(
            "PhysicalRegion",
            {
                "RegionType": "HandlerMemory",
                "Size": handler_memory_size,
                "Align": 0x10000,
                "Type": "I",
                "Bank": 0,
                "Range": str(handler_memory_constr),
            },
        )

    def setupMemoryFillPattern(self):
        fill_pattern, valid = self.genThread.getOption("MemoryFillPattern")
        if valid:
            self.setGlobalState("MemoryFillPattern", fill_pattern)

    def getHandlerMemorySize(self):
        return 0x2000 * 3

    def setupThreadGroup(self):
        self.partitionThreadGroup("Random", group_num=1)

    def _getHandlerMemoryConstraint(self):
        # Need to ensure the handler memory doesn't intersect the boot region
        # or initial PC of any thread
        handler_memory_constr = ConstraintSet(0, 0xFFFFFFFFFFFFFFFF)
        for thread_id in range(self.getThreadNumber()):
            handler_memory_constr.subRange(
                PcConfig.get_boot_pc(thread_id),
                (PcConfig.get_boot_pc(thread_id) + PcConfig.get_boot_region_size() - 1),
            )
            handler_memory_constr.subValue(PcConfig.get_initial_pc(thread_id))

        return handler_memory_constr


#  EnvGPGPU class
#  GPGPU environment class


class EnvGPGPU(Env):
    def __init__(self, interface):
        super().__init__(interface)
        self.defaultInitSeqClass = GlobalInitSeqGPGPU

    def addThreadSplitterSequence(self):
        #ToDO Shawn should remove multi instr
        #self.afterSequences.append(
        #    ThreadSplitterSequence(None, self.numberCores, self.numberThreads)
        #)
        Log.notice("Shawn should remove multi instr")
